package com.example.safelib

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.widget.TextView

import com.example.safelib.bean.SafeLineInfoBean
import com.github.mikephil.charting.charts.Chart
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.MarkerView
import com.github.mikephil.charting.data.CandleEntry
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.utils.MPPointF
import com.github.mikephil.charting.utils.Utils
import kotlinx.android.synthetic.main.safe_markview.view.*

import java.lang.ref.WeakReference

class LineChartMarkView(
    context: Context,
    private val format_realtimes: List<String>,
    private val sensorInfoBean: SafeLineInfoBean?
) : MarkerView(context, R.layout.safe_markview) {
    /**
     * Constructor. Sets up the MarkerView with a custom layout resource.
     *
     * @param context
     * @param layoutResource the layout resource to use for the MarkerView
     */
    private lateinit var mWeakChart: WeakReference<Chart<*>>

    override fun refreshContent(e: Entry, highlight: Highlight?) {
        var valueY = e.y.toString() + ""
        if (sensorInfoBean != null) {
            if (sensorInfoBean.typename == "开关量") {
                if (e.y == 0.0f) {
                    valueY = sensorInfoBean.offdescribe
                }
                if (e.y == 1.0f) {
                    valueY = sensorInfoBean.ondescribe
                }
            }
        }

        //展示自定义X轴值 后的X轴内容
        if (e is CandleEntry) {
            mk_value.text = Utils.formatNumber(e.high, 0, true)
        } else {
            if (format_realtimes.size > e.x.toInt() && e.x.toInt() >= 0 && format_realtimes[e.x.toInt()] != null && format_realtimes[e.x.toInt()].isNotEmpty())
            //非空判断;
                mk_date.text = "时间：" + format_realtimes[e.x.toInt()]
            mk_value.text = "测值：$valueY"
            mk_sen.text = sensorInfoBean!!.sensorname
        }
        super.refreshContent(e, highlight)


    }

    override fun setChartView(chart: Chart<*>) {
        mWeakChart = WeakReference(chart)
    }

    override fun getChartView(): Chart<*>? {
        return if (mWeakChart == null) null else mWeakChart!!.get()
    }

    override fun getOffsetForDrawingAtPoint(posX: Float, posY: Float): MPPointF {
        val offset = offset
        val chart = chartView
        val width = width.toFloat()
        val height = height.toFloat()
        // posY \posX 指的是markerView左上角点在图表上面的位置
        //处理Y方向
        if (posY <= height + ARROW_SIZE) {// 如果点y坐标小于markerView的高度，如果不处理会超出上边界，处理了之后这时候箭头是向上的，我们需要把图标下移一个箭头的大小
            offset.y = ARROW_SIZE.toFloat()
        } else {//否则属于正常情况，因为我们默认是箭头朝下，然后正常偏移就是，需要向上偏移markerView高度和arrow size，再加一个stroke的宽度，因为你需要看到对话框的上面的边框
            offset.y =
                -height - ARROW_SIZE.toFloat() - STOKE_WIDTH // 40 arrow height   5 stroke width
        }
        //处理X方向，分为3种情况，1、在图表左边 2、在图表中间 3、在图表右边
        //
        if (posX > chart!!.width - width) {//如果超过右边界，则向左偏移markerView的宽度
            offset.x = -width
        } else {//默认情况，不偏移（因为是点是在左上角）
            offset.x = 0f
            if (posX > width / 2) {//如果大于markerView的一半，说明箭头在中间，所以向右偏移一半宽度
                offset.x = -(width / 2)
            }
        }
        return offset

    }

    override fun draw(canvas: Canvas, posX: Float, posY: Float) {
        val paint = Paint()//绘制边框的画笔
        paint.strokeWidth = STOKE_WIDTH
        paint.style = Paint.Style.STROKE
        paint.strokeJoin = Paint.Join.ROUND
        paint.color = Color.BLUE

        val whitePaint = Paint()//绘制底色的画笔
        whitePaint.style = Paint.Style.FILL
        whitePaint.color = resources.getColor(R.color.colorDBlue)

        val chart = chartView
        val width = width.toFloat()
        val height = height.toFloat()

        val offset = getOffsetForDrawingAtPoint(posX, posY)
        val saveId = canvas.save()

        var path = Path()
        if (posY < height + ARROW_SIZE) {//处理超过上边界
            path = Path()
            path.moveTo(0f, 0f)
            if (posX > chart!!.width - width) {//超过右边界
                path.lineTo(width - ARROW_SIZE, 0f)
                path.lineTo(width, (-ARROW_SIZE).toFloat())
                path.lineTo(width, 0f)
            } else {
                if (posX > width / 2) {//在图表中间
                    path.lineTo(width / 2 - ARROW_SIZE / 2, 0f)
                    path.lineTo(width / 2, (-ARROW_SIZE).toFloat())
                    path.lineTo(width / 2 + ARROW_SIZE / 2, 0f)
                } else {//超过左边界
                    path.lineTo(0f, (-ARROW_SIZE).toFloat())
                    path.lineTo((0 + ARROW_SIZE).toFloat(), 0f)
                }
            }
            path.lineTo(0 + width, 0f)
            path.lineTo(0 + width, 0 + height)
            path.lineTo(0f, 0 + height)
            path.lineTo(0f, 0f)
            path.offset(posX + offset.x, posY + offset.y)
        } else {//没有超过上边界
            path = Path()
            path.moveTo(0f, 0f)
            path.lineTo(0 + width, 0f)
            path.lineTo(0 + width, 0 + height)
            if (posX > chart!!.width - width) {
                path.lineTo(width, height + ARROW_SIZE)
                path.lineTo(width - ARROW_SIZE, 0 + height)
                path.lineTo(0f, 0 + height)
            } else {
                if (posX > width / 2) {
                    path.lineTo(width / 2 + ARROW_SIZE / 2, 0 + height)
                    path.lineTo(width / 2, height + ARROW_SIZE)
                    path.lineTo(width / 2 - ARROW_SIZE / 2, 0 + height)
                    path.lineTo(0f, 0 + height)
                } else {
                    path.lineTo((0 + ARROW_SIZE).toFloat(), 0 + height)
                    path.lineTo(0f, height + ARROW_SIZE)
                    path.lineTo(0f, 0 + height)
                }
            }
            path.lineTo(0f, 0f)
            path.offset(posX + offset.x, posY + offset.y)
        }

        // translate to the correct position and draw
        canvas.drawPath(path, whitePaint)
        canvas.drawPath(path, paint)
        canvas.translate(posX + offset.x, posY + offset.y)
        draw(canvas)
        canvas.restoreToCount(saveId)
    }

    companion object {
        private const val STOKE_WIDTH = 5f//这里对于stroke_width的宽度也要做一定偏移
        const val ARROW_SIZE = 40 // 箭头的大小
    }

}
